import json
import uuid
from datetime import datetime


class OrderItem:
    """
    订单项类，代表订单中的单个商品
    """
    def __init__(self, product, quantity):
        self._product = product
        self._quantity = quantity
        self._price = product.price  # 记录下单时的价格
    
    def get_total_price(self):
        """获取订单项总价"""
        return self._price * self._quantity
    
    def to_dict(self):
        """将订单项转换为字典"""
        return {
            'product_id': self._product.product_id,
            'product_name': self._product.name,
            'quantity': self._quantity,
            'price': self._price,
            'total_price': self.get_total_price()
        }
    
    # Getter方法
    @property
    def product(self):
        return self._product
    
    @property
    def quantity(self):
        return self._quantity
    
    @property
    def price(self):
        return self._price


class Order:
    """
    订单类，代表用户的购物订单
    """
    # 订单状态
    STATUS_PENDING = "Pending"
    STATUS_PROCESSING = "Processing"
    STATUS_SHIPPED = "Shipped"
    STATUS_DELIVERED = "Delivered"
    STATUS_CANCELLED = "Cancelled"
    
    def __init__(self, order_id, customer_id, items, shipping_address, payment_method):
        self._order_id = order_id
        self._customer_id = customer_id
        self._items = items  # OrderItem列表
        self._shipping_address = shipping_address
        self._payment_method = payment_method
        self._status = Order.STATUS_PENDING
        self._order_date = datetime.now()
        self._payment_status = False
        self._tracking_number = None
    
    def calculate_total(self):
        """计算订单总金额"""
        return sum(item.get_total_price() for item in self._items)
    
    def update_status(self, status):
        """更新订单状态"""
        valid_statuses = [
            Order.STATUS_PENDING,
            Order.STATUS_PROCESSING,
            Order.STATUS_SHIPPED,
            Order.STATUS_DELIVERED,
            Order.STATUS_CANCELLED
        ]
        if status in valid_statuses:
            self._status = status
            return True
        return False
    
    def process_payment(self):
        """处理支付"""
        self._payment_status = True
        return True
    
    def set_tracking_number(self, tracking_number):
        """设置物流单号"""
        self._tracking_number = tracking_number
    
    def to_dict(self):
        """将订单信息转换为字典"""
        return {
            'order_id': self._order_id,
            'customer_id': self._customer_id,
            'items': [item.to_dict() for item in self._items],
            'shipping_address': self._shipping_address,
            'payment_method': self._payment_method,
            'status': self._status,
            'order_date': self._order_date.strftime('%Y-%m-%d %H:%M:%S'),
            'payment_status': self._payment_status,
            'tracking_number': self._tracking_number,
            'total_amount': self.calculate_total()
        }
    
    # Getter方法
    @property
    def order_id(self):
        return self._order_id
    
    @property
    def customer_id(self):
        return self._customer_id
    
    @property
    def items(self):
        return self._items
    
    @property
    def shipping_address(self):
        return self._shipping_address
    
    @shipping_address.setter
    def shipping_address(self, value):
        self._shipping_address = value
    
    @property
    def payment_method(self):
        return self._payment_method
    
    @property
    def status(self):
        return self._status
    
    @property
    def order_date(self):
        return self._order_date
    
    @property
    def payment_status(self):
        return self._payment_status
    
    @property
    def tracking_number(self):
        return self._tracking_number


class OrderManager:
    """
    订单管理器类，负责订单的创建、查找、更新等功能
    """
    def __init__(self, data_file="orders.json", product_manager=None, user_manager=None):
        self._orders = {}
        self._data_file = data_file
        self._product_manager = product_manager
        self._user_manager = user_manager
        self._load_orders()
    
    def _load_orders(self):
        """从文件加载订单数据"""
        try:
            with open(self._data_file, 'r', encoding='utf-8') as f:
                orders_data = json.load(f)
                for order_data in orders_data:
                    # 由于从文件加载时无法直接恢复OrderItem对象的product引用
                    # 这里只保存原始数据，实际使用时通过订单ID查找
                    self._orders[order_data['order_id']] = order_data
        except FileNotFoundError:
            pass
        except json.JSONDecodeError:
            pass
        except Exception as e:
            print(f"加载订单数据时出错: {e}")
    
    def save_orders(self):
        """保存订单数据到文件"""
        # 转换为可序列化的字典列表
        orders_data = []
        for order in self._orders.values():
            if isinstance(order, Order):
                orders_data.append(order.to_dict())
            else:
                # 如果是原始数据字典，直接添加
                orders_data.append(order)
        
        with open(self._data_file, 'w', encoding='utf-8') as f:
            json.dump(orders_data, f, ensure_ascii=False, indent=2)
    
    def create_order(self, customer_id, items_data, shipping_address, payment_method):
        """
        创建新订单
        items_data格式: [{"product_id": "xxx", "quantity": 1}, ...]
        """
        # 验证用户是否存在
        if self._user_manager:
            customer = self._user_manager.get_user_by_id(customer_id)
            if not customer:
                return None, "用户不存在"
        
        # 验证并创建订单项
        order_items = []
        for item_data in items_data:
            product_id = item_data['product_id']
            quantity = item_data['quantity']
            
            # 获取产品
            product = self._product_manager.get_product_by_id(product_id)
            if not product:
                return None, f"产品ID {product_id} 不存在"
            
            # 检查库存
            if product.stock < quantity:
                return None, f"产品 {product.name} 库存不足"
            
            # 创建订单项
            order_item = OrderItem(product, quantity)
            order_items.append(order_item)
        
        # 创建订单
        order_id = f"o{str(uuid.uuid4())[:8]}"
        order = Order(order_id, customer_id, order_items, shipping_address, payment_method)
        
        # 扣减库存
        for item in order_items:
            item.product.sell(item.quantity)
            
            # 更新卖家销售额
            if self._user_manager:
                seller = self._user_manager.get_user_by_id(item.product.seller_id)
                if seller and hasattr(seller, 'update_sales'):
                    seller.update_sales(item.get_total_price())
        
        # 处理支付
        order.process_payment()
        
        # 保存订单
        self._orders[order.order_id] = order
        self.save_orders()
        
        # 保存产品和用户数据
        if self._product_manager:
            self._product_manager.save_products()
        if self._user_manager:
            self._user_manager.save_users()
        
        return order, "订单创建成功"
    
    def get_order_by_id(self, order_id):
        """通过ID查找订单"""
        order = self._orders.get(order_id)
        if isinstance(order, dict) and self._product_manager:
            # 如果是原始数据字典，尝试重建Order对象
            try:
                items_data = order['items']
                items = []
                for item_dict in items_data:
                    product = self._product_manager.get_product_by_id(item_dict['product_id'])
                    if product:
                        item = OrderItem(product, item_dict['quantity'])
                        items.append(item)
                
                # 创建Order对象
                order_obj = Order(
                    order['order_id'],
                    order['customer_id'],
                    items,
                    order['shipping_address'],
                    order['payment_method']
                )
                
                # 恢复其他属性
                order_obj.update_status(order['status'])
                if order['payment_status']:
                    order_obj.process_payment()
                if order['tracking_number']:
                    order_obj.set_tracking_number(order['tracking_number'])
                
                return order_obj
            except Exception as e:
                print(f"重建订单对象时出错: {e}")
                return None
        return order
    
    def get_orders_by_customer(self, customer_id):
        """获取用户的所有订单"""
        orders = []
        for order_id, order in self._orders.items():
            if isinstance(order, Order) and order.customer_id == customer_id:
                orders.append(order)
            elif isinstance(order, dict) and order.get('customer_id') == customer_id:
                order_obj = self.get_order_by_id(order_id)
                if order_obj:
                    orders.append(order_obj)
        return orders
    
    def get_orders_by_seller(self, seller_id):
        """获取卖家相关的所有订单"""
        if not self._product_manager:
            return []
        
        orders = []
        # 获取卖家的所有产品
        seller_products = self._product_manager.get_products_by_seller(seller_id)
        product_ids = {p.product_id for p in seller_products}
        
        # 查找包含卖家产品的订单
        for order_id, order in self._orders.items():
            order_obj = order if isinstance(order, Order) else self.get_order_by_id(order_id)
            if order_obj:
                for item in order_obj.items:
                    if item.product.product_id in product_ids:
                        orders.append(order_obj)
                        break
        
        return orders
    
    def update_order_status(self, order_id, status):
        """更新订单状态"""
        order = self.get_order_by_id(order_id)
        if order and order.update_status(status):
            self._orders[order_id] = order
            self.save_orders()
            
            # 如果订单取消，恢复库存
            if status == Order.STATUS_CANCELLED:
                for item in order.items:
                    item.product.update_stock(item.quantity)
                    
                    # 更新卖家销售额
                    if self._user_manager:
                        seller = self._user_manager.get_user_by_id(item.product.seller_id)
                        if seller and hasattr(seller, 'update_sales'):
                            seller.update_sales(-item.get_total_price())
                
                # 保存产品和用户数据
                if self._product_manager:
                    self._product_manager.save_products()
                if self._user_manager:
                    self._user_manager.save_users()
            
            return True
        return False
    
    def set_tracking_number(self, order_id, tracking_number):
        """设置订单物流单号"""
        order = self.get_order_by_id(order_id)
        if order:
            order.set_tracking_number(tracking_number)
            order.update_status(Order.STATUS_SHIPPED)
            self._orders[order_id] = order
            self.save_orders()
            return True
        return False
    
    def get_all_orders(self):
        """获取所有订单"""
        all_orders = []
        for order_id, order in self._orders.items():
            if isinstance(order, Order):
                all_orders.append(order)
            else:
                order_obj = self.get_order_by_id(order_id)
                if order_obj:
                    all_orders.append(order_obj)
        return all_orders
    
    def get_orders_by_status(self, status):
        """根据状态获取订单"""
        all_orders = self.get_all_orders()
        return [order for order in all_orders if order.status == status]